// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rbchat.logic.chat_friend.vv;

import android.app.Activity;
import android.app.Dialog;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import com.eva.android.DelayedHandler;
import com.eva.android.NewAsyncTask;
import com.eva.android.widget.WidgetUtils;
import com.eva.android.widget.WidgetUtils.ToastType;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.R;
import com.x52im.rbchat.cache.ImageCacheLoader;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rbchat.logic.chat_friend.utils.MessageHelper;
import com.x52im.rbchat.logic.chat_friend.utils.RealTimeVoiceMessageHelper;
import com.x52im.rbchat.logic.chat_root.model.VoipRecordMeta;
import com.x52im.rbchat.utils.PromtHelper;
import com.x52im.rbchat.network.im.ChatMessageEventListener;

import java.text.MessageFormat;
import java.util.Observer;

/**
 * 用户处理好友发送过来的实时语音权限对话框.
 * <p>
 * 本类中用于处理实时语音时的交互.
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class VoiceCallOutDialog extends Dialog
{
	// 默认30秒内没有处理完成则超时退出
	public final static int DEFAULT_CALLING_TIMEOUT = 30 * 1000;//15 * 1000;
			
	private final static String TAG = VoiceCallOutDialog.class.getSimpleName();
	
	private Activity parentActivity = null;
	private String parentFriendUID = null;
	
	private TextView viewNickName = null;
	/** 按钮：结束 */
	private View btnEnd = null;
	/** 好友头像 */	
	private ImageView viewAvatar = null;
	
	private MediaPlayer promtMp = null;
	
	/** 
	 * 音视频聊天呼出事件观察者（本观察者将在{@link ChatMessageEventListener}收到对方（视频聊天接收方）的“同意”或“不同意”的处理时被通知）. */
	private Observer realTimeVoiceCallOutObserver = (observable, data) -> {
		int responseCode = (Integer)data;
		// 对方拒绝了我
		if(responseCode == 0) {
			showHint(parentActivity.getString(R.string.real_time_chat_request_be_refused));
			fireEndExtra();
			dismissNotSendReject();
		}
		// 对方同意了视频聊天哦
		else if(responseCode == 1) {
			showHint(parentActivity.getString(R.string.real_time_chat_request_be_agree));

			// TODO DELETE!!
			Log.d("BBBBBBBB", "好友同意了你的实时语音聊天请求！");

			fireWhenFriendAccept();

			// ** 注意：这里是正常同意
			dismissNotSendReject();
		}
		else {
			WidgetUtils.showToast(parentActivity
					, MessageFormat.format("Obtained the feedback,but responseCode={0},unkown parameter!", responseCode));
			VoiceCallOutDialog.this.dismiss();
		}
	};
	
	// 超时处理Handler
	private DelayedHandler delayedHandler = new DelayedHandler(DEFAULT_CALLING_TIMEOUT){
		@Override
		protected void fireRun() {
			// 发出一条音视频聊天记录（这样的话，本地和远端都会有记录的哟）
			MessageHelper.sendVoipRecordMessageAsync(
					// context用全局Application对象，确保消息的发送不依赖于本Activity的生命周期
					MyApplication.getInstance2()
					, parentFriendUID
					, new VoipRecordMeta(VoipRecordMeta.VOIP_TYPE_VOICE, VoipRecordMeta.RECORD_TYPE_CALLING_TIMEOUT)
					, null);

			WidgetUtils.showToastLong(parentActivity, parentActivity.getString(R.string.real_time_chat_request_timeout), ToastType.WARN);
			dismissImpl(false);
		}
	};
	
	// ！！！！！！！！ FOR TEST!
	private VideoCallOutActivity.NewVVReceiveEventListener newVVReceiveEventListener = null;
	
	protected void _onResume() 
	{
		MyApplication.getInstance(parentActivity).getIMClientManager().getTransDataListener().setRealTimeVoiceCallOutObserver(realTimeVoiceCallOutObserver);
		
		if(newVVReceiveEventListener != null)
			newVVReceiveEventListener.setBack(false);
	}
	protected void _onPause()
	{
		MyApplication.getInstance(parentActivity).getIMClientManager().getTransDataListener().setRealTimeVoiceCallOutObserver(null);
		
		if(newVVReceiveEventListener != null)
			newVVReceiveEventListener.setBack(true);
	}
	
	public void dismissNotSendReject()
	{
		_onPause();
		_finish(true, false);
		super.dismiss();
	}
	
	@Override
	public void dismiss()
	{
		dismissImpl(true);
	}

	protected void dismissImpl(boolean sendVoipRecordForCancel)
	{
		_onPause();
		_finish(false, sendVoipRecordForCancel);
		super.dismiss();
	}
	
	/**
	 * @param finishNotSendReject 当正常进入到音视频界面时，就不需要发送这个拒绝命令了，本界面中其它场合下
	 * 发送的拒绝命令相当于“结束”（比如程序崩溃这样的非正常退出行为时）。
	 */
	public void _finish(boolean finishNotSendReject, boolean sendVoipRecordForCancel)
	{
		// ！！！！！！！！ FOR TEST!
		VVP2PProvider.getInstance(parentActivity).getP2PController().unRegistryRequestEventListener(newVVReceiveEventListener);
	
		if(delayedHandler != null) {
			delayedHandler.stop();
			delayedHandler = null;
		}

        try {
            if(promtMp != null)
                promtMp.stop();
        }
        catch (Exception e) {
            Log.w(TAG, e);
        }
		
		if(!finishNotSendReject) {
			sendEndCall(sendVoipRecordForCancel);
		}
//		super.finish();
	}
	
	public VoiceCallOutDialog(Activity parentActivity, String parentFriendUID) 
	{
		super(parentActivity, R.style.voice_call_dialog);
		this.parentActivity = parentActivity;
		this.parentFriendUID = parentFriendUID;
	}
	public VoiceCallOutDialog(Activity parentActivity, int theme, String parentFriendUID)
	{
		super(parentActivity, theme);
		this.parentActivity = parentActivity;
		this.parentFriendUID = parentFriendUID;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		// 初始化
		init();

		// 以下代码用于解决底部导航栏是黑色的问题（资料：http://www.yiidian.com/questions/260426）
		try{
			getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
		} catch (Exception e) {
			Log.w(TAG, e);
		}

		_onResume();
	}
	
	private void init()
	{
		initViews();
		initListeners();
	}
	
	private void initViews()
	{
		this.setContentView(R.layout.voice_call_out_dialog);
		this.setCanceledOnTouchOutside(false);
		
		viewNickName = (TextView)this.findViewById(R.id.chatting_real_time_voice_request_out_dialog_nickNameView);
		btnEnd = (ViewGroup)this.findViewById(R.id.chatting_real_time_voice_request_out_dialog_end_btn);
		viewAvatar = (ImageView)this.findViewById(R.id.chatting_real_time_voice_request_out_dialog_target_avatarView);

		//** 对方的好友信息
		RosterElementEntity friendInfo = MyApplication.getInstance2().getIMClientManager().getFriendsListProvider().getFriendInfoByUid2(parentFriendUID);

		// ** 显示头像和昵称
		if(friendInfo != null) {
			ImageCacheLoader.loadAvatarImgWithGlide(parentActivity, friendInfo.getUser_uid(), friendInfo.getUserAvatarFileName(), viewAvatar
					, 50, R.drawable.default_avatar_yuan_100_3x, true, false);//30
			viewNickName.setText(friendInfo.getNickname());
		}
		
		// ！！！！！！！！ FOR TEST!
		//** 注册P2P事件监听
		newVVReceiveEventListener = new VideoCallOutActivity.NewVVReceiveEventListener(parentActivity);
		VVP2PProvider.getInstance(parentActivity).getP2PController().registryRequestEventListener(newVVReceiveEventListener);
//		//** P2P打洞请求（首先尝试P2P打洞哦）
//		VVP2PProvider.getInstance(parentActivity).requestP2P(Long.parseLong(parentFriendUID));
		//** 
		promtMp = PromtHelper.calling2Promt(parentActivity, parentFriendUID);
		//** 发出聊天请求
		sendRequest();
	}
	
//	/**
//	 * 拒绝对方的请求后要做的事。子类可重写本方法实现ui的展现.
//	 */
//	protected void fireRejectExtra()
//	{
//		// 默认什么也不做
//	}
	
	public void showHint(String text)
	{
		// 播放提示音
		PromtHelper.playendPromt(parentActivity);
//		viewHint.setText(text);
		WidgetUtils.showToast(parentActivity, text, ToastType.INFO);
	}
	
	private void sendRequest()
	{
		// 新聊天框架中的网络数据发送需要放到异步线程里（Android2.3以上版本要求网络交互不允许发生在主线程里）
		new NewAsyncTask<Object, Integer, Integer>(){
			@Override
			protected Integer doInBackground(Object... params) {
				RosterElementEntity friendERR = MyApplication.getInstance(parentActivity)
						.getIMClientManager().getFriendsListProvider().getFriendInfoByUid(parentFriendUID);
				int code = RealTimeVoiceMessageHelper.sendRealTimeVoiceRequest$Requestting_from$a(parentActivity
						, friendERR.getUser_uid()
						, MyApplication.getInstance(parentActivity).getIMClientManager().getLocalUserInfo().getUser_uid()
						, false, -1);
				return code;
			}

			@Override
			protected void onPostExecute(Integer code) {
				if(code == 0) {
					Log.d(TAG, "Request has been sent out,please wait...");
				}
				else {
					showHint(parentActivity.getString(R.string.real_time_chat_request_send_faild));
					VoiceCallOutDialog.this.dismiss();
				}
			}
		}.execute();
	}
	
	private void sendEndCall(final boolean sendVoipRecordForCancel)
	{
		// 新聊天框架中的网络数据发送需要放到异步线程里（Android2.3以上版本要求网络交互不允许发生在主线程里）
		new NewAsyncTask<Object, Integer, Integer>(){
			@Override
			protected Integer doInBackground(Object... params) {
				RosterElementEntity friendERR = MyApplication.getInstance(parentActivity)
						.getIMClientManager().getFriendsListProvider().getFriendInfoByUid(parentFriendUID);
				int code = RealTimeVoiceMessageHelper.sendVideoAndVoiceRequest$Abort_from$a(parentActivity
						, friendERR.getUser_uid()
						, MyApplication.getInstance(parentActivity).getIMClientManager().getLocalUserInfo().getUser_uid());
				return code;
			}

			@Override
			protected void onPostExecute(Integer code) {
				if(code == 0) {
					showHint(parentActivity.getString(R.string.real_time_chat_request_canceled));

					if(sendVoipRecordForCancel) {
						// 发出一条音视频聊天记录（这样的话，本地和远端都会有记录的哟）
						MessageHelper.sendVoipRecordMessageAsync(
								// context用全局Application对象，确保消息的发送不依赖于本Activity的生命周期
								MyApplication.getInstance2()
								, parentFriendUID
								, new VoipRecordMeta(VoipRecordMeta.VOIP_TYPE_VOICE, VoipRecordMeta.RECORD_TYPE_REQUEST_CANCEL)
								, null);
					}
				}
				else {
					Log.w(VideoCallOutActivity.class.getSimpleName(), "Canceled request is failed to send.");
					WidgetUtils.showToast(parentActivity
							, parentActivity.getString(R.string.real_time_chat_request_canceled_request_send_faild)
							, ToastType.WARN);
				}
			}
		}.execute();
	}
	
	protected void initListeners()
	{
		btnEnd.setOnClickListener(v -> {
			fireEndExtra();
			VoiceCallOutDialog.this.dismiss();
		});
	}
	
	/**
	 * 对方同意后要做的事。子类可重写本方法实现业务逻辑.
	 */
	protected void fireWhenFriendAccept()
	{
		// 默认什么也不做
	}
	
	/**
	 * 结束后要做的事。子类可重写本方法实现ui的展现.
	 * 目前用于2种场景下：本地在呼叫时“挂掉”、对方收到请求后“拒绝”时都会调用本方法.
	 */
	protected void fireEndExtra()
	{
		// 默认什么也不做
	}
}
